/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.db.sql;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.lambkit.util.SqlKit;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class JoinOn implements Serializable {
	private SqlJoinMode type = SqlJoinMode.INNER_JOIN;
	private String mainTableName;
	private String joinTableName;
	private String mainAlias;
	private String joinAlias;
	private List<JoinOnField> joinOnFields;
	private ColumnsGroup columnsGroup;
	private String loadColumns = null;

	private List<String> warns = new ArrayList<>();
	
	public JoinOn() {
		columnsGroup = new ColumnsGroup();
		joinOnFields = CollUtil.newArrayList();
	}

	public JoinOn(String mainTableName, String mainTableField, String joinTableName, String joinTableField,
			SqlJoinMode type, Columns cols) {
		this.type = type;
		init(mainTableName, mainTableField, joinTableName, joinTableField);
		columnsGroup.addColumns(cols);
	}

	public JoinOn(String mainTableName, String mainTableField, String joinTableName, String joinTableField,
			Columns cols) {
		init(mainTableName, mainTableField, joinTableName, joinTableField);
		columnsGroup.addColumns(cols);
	}

	public JoinOn(String mainTableName, String mainTableField, String joinTableName, String joinTableField,
			SqlJoinMode type) {
		this.type = type;
		init(mainTableName, mainTableField, joinTableName, joinTableField);
	}

	public JoinOn(String mainTableName, String mainTableField, String joinTableName, String joinTableField) {
		init(mainTableName, mainTableField, joinTableName, joinTableField);
	}

	private void init(String mainTableName, String mainTableField, String joinTableName, String joinTableField) {
		setMainTableName(mainTableName);
		setMainAlias(mainTableName);
		setJoinTableName(joinTableName);
		setJoinAlias(joinTableName);
		if(this.joinOnFields==null) {
			this.joinOnFields = CollUtil.newArrayList();
		}
		if(columnsGroup==null) {
			columnsGroup = new ColumnsGroup();
		}
		if(StrUtil.isNotBlank(mainTableField)) {
			mainTableField = mainTableField.trim();
			String sls1 = SqlKit.transactSQLInjection(mainTableField);
			if (SqlKit.validateSQL(sls1)) {
				mainTableField = sls1;
			} else {
				getWarns().add("mainTableField: " + mainTableField + " is not validate sql");
			}
		}
		if(StrUtil.isNotBlank(joinTableField)) {
			joinTableField = joinTableField.trim();
			String sls2 = SqlKit.transactSQLInjection(joinTableField);
			if(SqlKit.validateSQL(sls2)) {
				joinTableField = sls2;
			} else {
				getWarns().add("joinTableField: " + joinTableField + " is not validate sql");
			}
		}
		this.joinOnFields.add(new JoinOnField(mainTableField, joinTableField));
	}

	/**
	 * 归集所有消息
	 * 
	 * @return
	 */
	public List<String> getMessageList() {
		List<String> msg = CollUtil.newArrayList();
		if (columnsGroup != null) {
			msg.addAll(columnsGroup.getMessageList());
		}
		if (CollUtil.isNotEmpty(getWarns())) {
			msg.addAll(getWarns());
		}
		return msg;
	}
	
	/**
	 * 归集所有引用
	 * 
	 * @return
	 */
	public List<String> getRefList() {
		List<String> msg = CollUtil.newArrayList();
		if (columnsGroup != null) {
			return columnsGroup.getRefList();
		}
		return msg;
	}

	public JoinOn mode(SqlJoinMode type) {
		this.type = type;
		return this;
	}

	public String getJoinTableName() {
		return joinTableName;
	}

	public JoinOn setJoinTableName(String joinTableName) {
		if(StrUtil.isNotBlank(joinTableName)) {
			joinTableName = joinTableName.trim();
			String sls = SqlKit.transactSQLInjection(joinTableName);
			if(SqlKit.validateSQL(sls)) {
				this.joinTableName = sls;
			} else {
				getWarns().add("joinTableName: " + joinTableName + " is not validate sql");
			}
			if(StrUtil.isBlank(joinAlias)) {
				joinAlias = joinTableName;
			}
		}
		return this;
	}

	public SqlJoinMode getType() {
		return type;
	}

	public JoinOn setType(SqlJoinMode type) {
		this.type = type;
		return this;
	}

	public String getMainTableName() {
		return mainTableName;
	}

	public void setMainTableName(String mainTableName) {
		if(StrUtil.isNotBlank(mainTableName)) {
			mainTableName = mainTableName.trim();
			String sls = SqlKit.transactSQLInjection(mainTableName);
			if(SqlKit.validateSQL(sls)) {
				this.mainTableName = sls;
			} else {
				getWarns().add("mainTableName: " + mainTableName + " is not validate sql");
			}
			if(StrUtil.isBlank(mainAlias)) {
				mainAlias = mainTableName;
			}
		}
	}

	public List<JoinOnField> getJoinOnFields() {
		return joinOnFields;
	}

	public void setJoinOnFields(List<JoinOnField> joinOnFields) {
		this.joinOnFields = joinOnFields;
	}

	public ColumnsGroup getColumnsGroup() {
		return columnsGroup;
	}

	public void setColumnsGroup(ColumnsGroup columnsGroup) {
		this.columnsGroup = columnsGroup;
	}

	public String getMainAlias() {
		return mainAlias;
	}

	public void setMainAlias(String mainAlias) {
		if(StrUtil.isNotBlank(mainAlias)) {
			mainAlias = mainAlias.trim();
			String sls = SqlKit.transactSQLInjection(mainAlias);
			if(SqlKit.validateSQL(sls)) {
				this.mainAlias = sls;
			} else {
				getWarns().add("mainAlias: " + mainAlias + " is not validate sql");
			}
		}
	}

	public String getJoinAlias() {
		return joinAlias;
	}

	public void setJoinAlias(String joinAlias) {
		if(StrUtil.isNotBlank(joinAlias)) {
			joinAlias = joinAlias.trim();
			String sls = SqlKit.transactSQLInjection(joinAlias);
			if (SqlKit.validateSQL(sls)) {
				this.joinAlias = sls;
			} else {
				getWarns().add("joinAlias: " + joinAlias + " is not validate sql");
			}
		}
	}

	public String getLoadColumns() {
		return loadColumns;
	}

	public void setLoadColumns(String loadColumns) {
		if(StrUtil.isNotBlank(loadColumns)) {
			loadColumns = loadColumns.trim();
			if(loadColumns.equals("*")) {
				this.loadColumns = loadColumns;
			} else {
				String sls = SqlKit.transactSQLInjection(loadColumns);
				if (SqlKit.validateSQL(sls)) {
					this.loadColumns = sls;
				} else {
					getWarns().add("loadColumns: " + loadColumns + " is not validate sql");
				}
			}
		}
	}

	public List<String> getWarns() {
		return warns;
	}

	public void setWarns(List<String> warns) {
		this.warns = warns;
	}


}
